#include<iostream>
#include<cstring>
#include<queue>
// #define ONLINE_GUDGE
using namespace std;
const int N = 110, INF = 0x3f3f3f3f;

int m, n;
int w[N][N], level[N]; // w 邻接矩阵存每条边的权重，level 数组存每个点的等级
int dist[N]; // 距离
bool st[N]; // 存储每个点是否已经是最短距离

int dijkstra(int down, int up) // 区间下限 区间上限
{
    memset(dist, 0x3f, sizeof dist);
    memset(st, 0, sizeof st); 

    dist[0] = 0; // 0 号点是起点，终点是 1 号点

    for (int i = 0; i < n; i ++ ) {
        int t = -1; // 每次取一个距离最小的点
        for (int i = 0; i <= n; i ++ ) // 这里从 0 号点开始，一共 n + 1 个点
            if (!st[i] && (t == -1 || dist[t] > dist[i]))
                t = i;

        st[t] = true; // 用 t 更新到其他点的距离，除了 0 号起点
        for (int i = 1; i <= n; i ++ ) {
            if (level[i] >= down && level[i] <= up) // 如果点 i 的等级在范围内才能被更新
                dist[i] = min(dist[i], dist[t] + w[t][i]);
        }
    }

    return dist[1]; // 返回起点到终点的距离
}

int main()
{
    #ifdef ONLINE_JUDGE

    #else
        freopen("./in.txt", "r", stdin);
    #endif

    ios::sync_with_stdio(0); cin.tie(0);
    
    cin >> m >> n;

    memset(w, 0x3f, sizeof w);
    for (int i = 1; i <= n; i ++ ) w[i][i] = 0;

    // 建图
    for (int i = 1; i <= n; i ++ ) {
        int price, cnt;
        cin >> price >> level[i] >> cnt; // 该物品价格 主人的地位等级 替代品总数
        w[0][i] = min(price, w[0][i]); // 建一条从虚拟源点到点 i 权值为 price 的边
        while (cnt -- ) { // 枚举每个替代品
            int id, cost;
            cin >> id >> cost;
            w[id][i] = min(w[id][i], cost); // 建立一条从点 id 到点 i 权值为 cost 的边
        }
    }

    // 枚举等级区间左端点 i，长度为 m，区间为 [i, i + m]
    int res = INF;
    for (int i = level[1] - m; i <= level[1]; i ++ ) res = min(res, dijkstra(i, i + m));

    cout << res << endl;

    return 0;
}